#include "SlopeRayColumn.h"

SlopeRayColumn::SlopeRayColumn(const Vector3f& origin, float dirX, float dirY, float* dirZ, int numRays) {
    this->origin = origin;
    this->dirX = dirX;
    this->dirY = dirY;
    this->dirZ = dirZ;
    this->numRays = numRays;
    this->flatRay = Ray(origin, Vector3f(dirX, dirY, 0));
}

Ray SlopeRayColumn::getRay(int index) const {
    Vector3f dir(dirX, dirY, dirZ[index]);
    dir.normalize();
    return Ray(origin, dir);
}

Ray SlopeRayColumn::getSlopeRay(int index) const {
    Vector3f dir(dirX, dirY, dirZ[index]);
    return Ray(origin, dir);
}

bool SlopeRayColumn::rectIndices(int& start, int& end, const Vector3f& min, const Vector3f& max) const {
    float minT, maxT;

    if (origin.timeInRect(minT, maxT, dirX, dirY, min.x, max.x, min.y, max.y)) {
        float diffZTop = max.z - origin.z;
        float diffZBottom = min.z - origin.z;

        float maxDirZ, minDirZ;
        if (diffZTop > 0.0) {
            maxDirZ = diffZTop / minT;
        } else {
            maxDirZ = diffZTop / maxT;
        }

        if (diffZBottom > 0.0) {
            maxDirZ = diffZBottom / minT;
        } else {
            maxDirZ = diffZBottom / maxT;
        }

        //TODO: optimize?
        for (; start < end; start++) {
            float currZ = dirZ[start];
            if (currZ > minDirZ) break;
        }

        for (int i = start; i < end; i++) {
            float currZ = dirZ[i];
            if (currZ > maxDirZ) end = i;
        }
        return true;
    } else {
        return false;
    }
}